<!--
 * @Author: WangShuai 1830773767@qq.com
 * @Date: 2025-06-16 18:05:52
 * @LastEditors: WangShuai 1830773767@qq.com
 * @LastEditTime: 2025-06-19 10:49:53
 * @FilePath: \vue3_admin_template\project\src\components\ThreeScene\ThreeScene.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template></template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
//引入three
import * as THREE from 'three'
import useSceneStore from '@/store/modules/threeScene'
//引入su7模型
// import {GLTFLoader}  from 'three/addons/loaders/GLTFLoader.js'
// import { RGBELoader} from 'three/addons/loaders/RGBELoader.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
import circle from '@/utils/three/mesh/CircleMesh.js'
import * as TWEEN from '@tweenjs/tween.js'
let scene: any
let tween
let materials: any = [] //车辆材质数组
//@ts-ignore  忽略ts检查
let currentModel: any = null // Store reference to the current model

//获取路由对象
let $route = useRoute()
//实例化GLTFloader
const gltfLoader = new GLTFLoader()
const initModel = () => {
  scene.add(circle) //向场景中添加CircleMesh
  circle.position.set(0, -0.03, 0)
  //加入全景
  //   const texture = new RGBELoader().load(
  //     '/src/assets/hdr/venice_sunset_1k.hdr',
  //     () => {
  //       texture.mapping = THREE.EquirectangularReflectionMapping
  //       // scene.background = texture //
  //       scene.environment = texture
  //     },
  //   )

  new RGBELoader().load(modelUrl.hdr, (texture) => {
    texture.mapping = THREE.EquirectangularReflectionMapping
    // scene.background = texture //
    scene.environment = texture
  })

  //   添加背景
  const backgroundTexture = new THREE.TextureLoader().load(modelUrl.background)
  backgroundTexture.wraps = backgroundTexture.wrapT = THREE.RepeatWrapping
  backgroundTexture.repeat.set(1, 1)
  scene.background = backgroundTexture

  //创建展厅地板
  const floorTexture = new THREE.TextureLoader().load(modelUrl.floorTexture)
  floorTexture.wraps = floorTexture.wrapT = THREE.RepeatWrapping
  floorTexture.repeat.set(1, 1)
  circle.material.aoMap = floorTexture //aoMap能让有阴影的地方更明显
  circle.material.aoMapIntensity = 1.5
  gltfLoader.load(modelUrl.su7, (gltf: any) => {
    const model = gltf.scene
    currentModel = model // Store the model reference
    model.traverse((mesh: any) => {
      if (mesh.isMesh) {
        mesh.castShadow = true
        materials.push(mesh.material)
      }
    })
    scene.add(model)
  })
  //加入光源 建一个环境光
  const ambientLight = new THREE.AmbientLight(0xf7f8fc, 0.5)
  scene.add(ambientLight)
  //平行光
  const directionalLight = new THREE.DirectionalLight(0xf7f8fc, 1)
  directionalLight.castShadow = true //灯光支持阴影
  //优化阴影效果
  directionalLight.shadow.color = new THREE.Color(0x000000) //黑色阴影
  directionalLight.shadow.mapSize.width = 2048 //默认阴影宽512
  directionalLight.shadow.mapSize.height = 2048 //默认阴影长512
  ;(directionalLight.shadow.radius = 8), //柔化阴影边缘
    directionalLight.position.set(0, 5, 0)
  scene.add(directionalLight)
  createColorSelector()
}
const changColorTranstion = (primColor: any, color: any) => {
  tween = new TWEEN.Tween(primColor)
    .to(color, 600)
    .easing(TWEEN.Easing.Cubic.InOut)
    .start()
  //将tween实例对党存储到仓库中
  useSceneStore().setTweenFn(tween)
}
//修改车漆颜色的流程
// 1,收集到所有有的车辆材质
//2,根据当前得到的颜色,更改车漆的材质
const changeCarBodyColor = (colorString: any) => {
  if (materials.length) {
    // materials.forEach(m => {
    //     if (m.name.includes('Car_body')) {
    //         m.color = new THREE.Color(colorString)
    //     }
    // })

    let bodyName = 'Car_body'
    const targetMaterial = materials.find((m: any) => m.name === bodyName)
    // console.log("targetMaterial",targetMaterial);
    if (targetMaterial) {
      // targetMaterial.color = new THREE.Color(colorString)
      changColorTranstion(targetMaterial.color, new THREE.Color(colorString))
    }
  }
}
const container = ref()
//创建颜色选择器UI
const createColorSelector = () => {
  const colors = [
    {
      name: '深海蓝',
      hex: '#1A9CB0',
    },
    {
      name: '玛瑙红',
      hex: '#A00039',
    },
    {
      name: '橄榄绿',
      hex: '#6E7555',
    },
    {
      name: '雅灰',
      hex: '#D6D7D9',
    },
    {
      name: '紫檀',
      hex: '#614C63',
    },
  ]
  if ($route.path == '/three') {
    container.value = document.createElement('div')
    container.value.className = 'color-selector'
    colors.forEach((color, index) => {
      const colorBtn = document.createElement('div')
      colorBtn.className = 'color-btn'
      colorBtn.setAttribute('data-color', color.hex)
      colorBtn.style.backgroundColor = color.hex

      //默认选中第一个
      if (index === 0) {
        colorBtn.classList.add('active')
      }
      //颜色名称标签
      const colorLabel = document.createElement('div')
      colorLabel.className = 'color-label'
      colorLabel.textContent = color.name
      colorBtn.appendChild(colorLabel)
      container.value.appendChild(colorBtn)
    })
    //使用事件委托添加点击事件
    container.value.addEventListener('click', function (event: any) {
      //查找被点击的按钮元素
      let targetBtn = event.target
      //如果点击的时标签元素,则获取其父元素(按钮)
      if (targetBtn.classList.contains('color-label')) {
        targetBtn = targetBtn.parentElement
      }
      //确认点击的时按钮元素
      if (targetBtn.classList.contains('color-btn')) {
        //移除所有按钮的active类
        const colorBtns = document.querySelectorAll('.color-btn')
        colorBtns.forEach((btn) => btn.classList.remove('active'))
        //添加active类到当前点击的按钮
        targetBtn.classList.add('active')
        //获取颜色值
        const color = targetBtn.getAttribute('data-color')
        // console.log("选中的颜色", color);
        // 这里不实现具体功能，由用户自行实现
        changeCarBodyColor(color)
      }
    })
    document.body.appendChild(container.value)
  }
}

onMounted(() => {
  scene = useSceneStore().scene
  //   console.log('object', scene)
  initModel()
})
onUnmounted(() => {
  if (container.value && container.value.parentNode) {
    // 移除事件监听器
    container.value.removeEventListener('click', null)
    // 从DOM中移除元素
    container.value.parentNode.removeChild(container.value)
    // 清空引用
    container.value = null
  }
})
</script>

<style scoped></style>
